#include <iostream>
using namespace std;

/*		多态：一个接口，多种形态
		静态多态：编译阶段决定
			> 函数重载
		动态多态: 在运行阶段
			动态多态的实现步骤：
				1 在基类中存在虚函数
				2 在派生类中重写基类的虚方法
				3 使用基类指针指向派生类对象，调用派生类方法

		首先在基类中存在虚函数，那么创建的对象将会增加4个字节的大小,在前四个字节中存放了指向
		虚函数列表的指针, 当运行时，如果基类的指针指向了派生类的对象,如果在派生类中重写类
		基类的虚函数，那么在虚函数列表中派生类的虚函数将会覆盖掉虚表中基类的函数地址，
		从而调用派生类的实现
*/

class Animal{
private:
	int 	year;
public:
	Animal(int year) 
		:year(year)
	{
	}

	Animal(){}
	//虚函数
	virtual void run() const { cout << "Animal::run..." << endl; }
	virtual void roar() const { cout << "Animal::roar..." << endl; }
};

class Dog : public Animal{
private:
	void run() const { cout << "Dog::run..." << endl; }
};

class Cat : public Animal{
public:
	//重写/覆盖基类的roar方法
	void roar() const { cout << "miao miao miao..."<< endl; }

	void eat() const { cout << "eat fish ..." << endl; }
};

//定义函数指针别名
typedef void(*func)(void);

int main(int argc, char **argv)
{
	cout << sizeof(Animal) << endl;		//4
	
	Animal animal(5);
	//int *p = (int*)&animal;
	//cout << "first four byte: " << *p << endl;
	
	Animal* p = new Cat();

	func fp = func(*((int*)*(int*)p));
	fp();

	fp = func(*(((int*)*(int*)p) + 1));
	fp();

	p = new Dog();
	p->run();
	p->roar();

	//p++;
	//cout << "last four byte: " << *p << endl;
/*
	Animal* p = new Cat();
	p->run();
	p->roar();				//多态实现
	//p->eat();
*/
	return 0;
}
